//
//  YsUploadManager.h
//  YsCloudFileManageSDK
//
//  Created by 宋宏康 on 2020/2/25.
//  Copyright © 2020 YJTSuper. All rights reserved.
//

#import "YsUploadManager.h"
#import "YsUploadManager+Tools.h"

@implementation YsUploadManager
//SingletonM(YsUploadManager);

static YsUploadManager *manager = nil;
static NSString *uploadListName = @"uploadList";

+ (instancetype)shareYsUploadManager
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[self alloc] init];
    });
    return manager;
}

- (NSMutableArray *)modelArray {
    
    if (_modelArray == nil) {
        _modelArray = [NSMutableArray array];
       NSArray *array = [YsCloudRealmTool getUploadTaskWithAccountCode:kAccountCode];
        for (int i = 0 ; i < array.count; i++) {
            YsCloudFileUploadReamModel *cloudFileUploadReamModel = [array objectAtIndex:i];
            YsDocUploadModel *model = [[YsDocUploadModel alloc] initWithProductUploadModel:NO];
            model.totalSize = cloudFileUploadReamModel.totalSize;
            model.filePath = cloudFileUploadReamModel.filePath;
            model.lastPathComponent = cloudFileUploadReamModel.mime;
            model.totalCount  = cloudFileUploadReamModel.totalCount;
            model.uploadedCount = cloudFileUploadReamModel.uploadedCount;
            model.fileHash = cloudFileUploadReamModel.md5;
            model.fileName = cloudFileUploadReamModel.fileName;
            model.createTime = cloudFileUploadReamModel.createTime;
            model.uploadStatus = cloudFileUploadReamModel.uploadStatus;
            model.accountCode = cloudFileUploadReamModel.accountCode;
            model.waitTaskTime = cloudFileUploadReamModel.waitTaskTime;
            model.fileUploadReamModel = cloudFileUploadReamModel;
            [_modelArray addObject:model];
        }
    }
   
    return _modelArray;
}


#pragma mark - 上传任务写入到realm
- (void)addUploadModel:(YsDocUploadModel *)model  {
    /// 添加模型
    [self.modelArray addObject:model];
    ///
    NSPredicate *query = [NSPredicate predicateWithFormat:@"accountCode == %@",kAccountCode];

    YsCloudFileManageSDKRealm *sdkRealm = (YsCloudFileManageSDKRealm *) [YsCloudFileRealmManager queryObjsWithPredicate:query targetClass:YsCloudFileManageSDKRealm.class].lastObject;
    
        [YsCloudFileRealmManager updateObj:^{
            [sdkRealm.uploadReamModelArray addObject:model.fileUploadReamModel];
        }];
    [self refreshCaches];
    [[NSNotificationCenter defaultCenter] postNotificationName:kSuperUploadFile object:nil];
}

- (void)removeUploadModel:(YsDocUploadModel *)model {
    
#if 1
//    model.isRunning = NO;
    [model.dataTask cancel];
#else
    model.isRunning = NO;
       [model.dataTask cancel];
       [self cleanPath:model.filePath];
       [self.modelArray removeObject:model];
       [self refreshCaches];
       [[NSNotificationCenter defaultCenter] postNotificationName:kSuperFinishedUpload object:nil];
       if (self.modelArray.count == 0) {
           [self postNotice];
       }
#endif
}

- (void)postNotice {
    
    [[NSNotificationCenter defaultCenter] postNotificationName:kSuperFinishedUpload object:nil];
}

- (void)refreshCaches {
    /// 更新数据库
//    [[NSUserDefaults standardUserDefaults] setObject:[YsDocUploadModel mj_keyValuesArrayWithObjectArray:self.modelArray ignoredKeys:@[@"progressBlock",@"isRunning",@"dataTask",@"fileUploadReamModel"]] forKey:uploadListName];
//    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)cancelAllUploadOperations {
    
    for (YsDocUploadModel *docUploadModel in self.modelArray) {
        [docUploadModel.dataTask cancel];
//        docUploadModel.uploadStatus =
//        docUploadModel.isRunning = NO;
    }
    
    [self refreshCaches];
}

- (void)removeAll {
    
    [self cancelAllUploadOperations];
    [self.modelArray  removeAllObjects];
    [self refreshCaches];
    [self clean];
    [self postNotice];
    
}


#pragma mark- continue upload
- (void)continueUploadWithModel:(YsDocUploadModel *)model {
//    SemaphoreBegin;
    if (model.uploadStatus != 3) return;
    __block NSInteger i = model.uploadedCount;
      NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
      [parameters setValue:model.accountCode forKey:@"uid"];
      [parameters setValue:model.fileName forKey:@"name"];
      [parameters setValue:@(i) forKey:@"chunk"];
      [parameters setValue:@(model.totalCount) forKey:@"chunks"];
      [parameters setValue:[YsFileUtil readDataWithfilePath:model.filePath].md5String forKey:@"hash"];
        
     NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:model.filePath];
       [handle seekToFileOffset:kSuperUploadBlockSize * i];
       NSData *blockData = [handle readDataOfLength:kSuperUploadBlockSize];
     [handle closeFile];

    
    NSLog(@"当前上传的切片数---:%zd",model.uploadedCount);
    
    NSString *requestUrl = kSuperUploadTestUrl;
#if 0
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//    NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:NSString.backgroundSessionIdentifier];
//       AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];
    // 设置超时时间
    manager.requestSerializer.timeoutInterval = 1000.f;
    manager.responseSerializer.acceptableContentTypes= [NSSet setWithObjects:@"text/html", nil];
#else
    AFHTTPSessionManager *manager = self.manager;
#endif
    NSURLSessionDataTask *dataTask =
    [manager POST:requestUrl parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        SemaphoreBegin;
     [formData appendPartWithFileData:blockData name:@"file" fileName:model.fileName mimeType:@"application/octet-stream"];
        SemaphoreEnd;
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        SemaphoreBegin;
      /// 上传完成
     if (model.uploadedCount == model.totalCount - 1){
         [self uploadFinishWithModel:model];
     }else{
         i ++;
         model.uploadedCount = i;
         [self continueUploadWithModel:model];
     }
        SemaphoreEnd;
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        SemaphoreBegin;
        model.error = error;
        model.uploadStatus = 6;
        [handle closeFile];
        [NSNotificationCenter.defaultCenter postNotificationName:kuploadError object:nil];
        SemaphoreEnd;
    }];
    model.dataTask = dataTask;
//    SemaphoreEnd;
}


#pragma mark - uploadFinish
- (void)uploadFinishWithModel:(YsDocUploadModel *)model
{
    SemaphoreBegin;
    NSString *mimeStr = (model.fileType == YsFileTypePhoto) ? @"image/png" :  @"image/png" ;
    [YsNetWorkManage uploadMoveFileWithuid:kAccountCode Withname:model.fileName Withsize:model.totalSize Withhash:model.fileHash Withmime:mimeStr success:^(YsResultModel *result) {
        NSLog(@"%@",result);
        model.uploadStatus = 4;
        [NSNotificationCenter.defaultCenter postNotificationName:kuploadFinish object:nil];
        [self checkUpload];
    } fail:^(NSError *error) {
        NSLog(@"%@",error);
        model.uploadStatus = 6;
        model.uploadedCount = 0;
        model.error = error;
        [NSNotificationCenter.defaultCenter postNotificationName:kuploadError object:nil];
    }];
    SemaphoreEnd;
}

#pragma mark -  获取云端切片数

- (void)getCloudNewBlockWithModel:(YsDocUploadModel *)model
{
    [YsNetWorkManage uploadcheckWithuid:kAccountCode Withhash:model.fileHash WitfileName:model.fileName WithfileSize:model.totalSize WithmaxFileCount:model.totalCount Withsize:model.totalSize success:^(YsResultModel *result) {
        NSLog(@"------%@",result);
    } fail:^(NSError *error) {
        NSLog(@"------%@",error);
    }];
}


#pragma mark- clean cache file
- (void)clean {
    NSString *cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
    NSString *path =  [cachesDirectory stringByAppendingPathComponent:@"video"];
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    [fileManager removeItemAtPath:path error:nil];
}

- (void)cleanPath:(NSString *)filePath {
    
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    [fileManager removeItemAtPath:filePath error:nil];
}

#pragma mark- write cache file
- (NSString *)writeToCacheVideo:(NSData *)data appendNameString:(NSString *)name {
    
    NSString *path = [self pathByAppendNameString:name];
    [data writeToFile:path atomically:NO];
    return path;
}

- (NSString *)writeToCacheUrl:(NSURL *)mediaUrl appendNameString:(NSString *)name {
    
    NSString *path = [self pathByAppendNameString:name];
    return path;
}


- (NSString *)pathByAppendNameString:(NSString *)name {
    
    NSString *cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
    NSString *createPath =  [cachesDirectory stringByAppendingPathComponent:@"video"];
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    [fileManager createDirectoryAtPath:createPath withIntermediateDirectories:YES attributes:nil error:nil];
    NSString *path = [cachesDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"/video/%.0f%@",[NSDate date].timeIntervalSince1970,name]];
    return path;
}


#pragma mark- saveRequest
- (void)saveRequest:(YsDocUploadModel *)model {
    model.uploadStatus = 4;
}

// 通过路径获取文件大小
- (long long)fileSizeAtPath:(NSURL *)mediaUrl {
    
    NSFileManager *manager =[NSFileManager defaultManager];
    if ([manager fileExistsAtPath:mediaUrl.path]){
        return [[manager attributesOfItemAtPath:mediaUrl.path error:nil] fileSize];
    }else {
        return 0;
    }
}

@end
